
package com.joysuch.wwyt.mh.storage.task;

import cn.zlg.common.util.CollectionUtils;
import com.google.common.collect.Lists;
import com.joysuch.wwyt.api.mh.service.MonitorPointDataAPIService;
import com.joysuch.wwyt.bp.repository.BpEnterpriseInfoDao;
import com.joysuch.wwyt.core.entity.BaseConfig;
import com.joysuch.wwyt.core.enums.BaseConfigCodes;
import com.joysuch.wwyt.core.service.BaseConfigService;
import com.joysuch.wwyt.mh.entity.MhAlarmLimitConfig;
import com.joysuch.wwyt.mh.mapper.CustomizeMonitorPointMapper;
import com.joysuch.wwyt.mh.repository.MhMonitoringPointDao;
import com.joysuch.wwyt.mh.service.MhMonitoringPointService;
import com.joysuch.wwyt.mh.storage.IMonitorPointDataHandler;
import com.joysuch.wwyt.mh.storage.MonitorPointData;
import com.joysuch.wwyt.risk.entity.RiskEvaluationControl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.*;

/**
 * 监控点数据获取任务
 *
 * @author qingzhou
 * 2019-11-20
 */
@Slf4j
@Component
public class MonitorPointDataExtractTask {

    @Resource
    private IMonitorPointDataHandler defaultIMonitorPointDataHandler;
    @Resource
    private MhMonitoringPointService mhMonitoringPointService;
    @Resource
    private MhMonitoringPointDao monitoringPointDao;
    @Resource
    private BaseConfigService baseConfigService;
    @Autowired
    private BpEnterpriseInfoDao enterpriseInfoDao;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private MonitorPointDataAPIService monitorPointDataAPIService;

    @Resource
    private CustomizeMonitorPointMapper monitorPointMapper;


    @Scheduled(initialDelay = 15000, fixedDelay = 10 * 1000)
    public void run() {

        try {
            List<Map<String, Object>> tenentIdAndOrgCode = enterpriseInfoDao.selectTenentIdAndOrgCodes();
            tenentIdAndOrgCode.forEach(m -> {
                Long tenantId = ((BigInteger) m.get("tenentId")).longValue();
                String orgCode = (String) m.get("orgCode");
                BaseConfig config = baseConfigService.findConfig(tenantId, orgCode,
                        BaseConfigCodes.MONITOR_POINT_HTTP_SERVER_URL);
                try {
                    List<Map<String, Object>> data = null;
                    if (config != null && StringUtils.isNotEmpty(config.getValue())) {
                        List<String> pointCodes = monitorPointMapper.findAll(tenantId, orgCode);
                        if (CollectionUtils.isEmpty(pointCodes)) {
                            return;
                        }
                        String readBody = toJsonBody(pointCodes);
                        HttpHeaders headers = getHttpHeaders();
                        HttpEntity<String> readEntity = new HttpEntity<>(readBody, headers);
                        ParameterizedTypeReference<List<Map<String, Object>>> readRespType = new ParameterizedTypeReference<List<Map<String, Object>>>() {
                        };
                        ResponseEntity<List<Map<String, Object>>> readResult = restTemplate
                                .exchange(config.getValue() + "/READ", HttpMethod.PUT, readEntity, readRespType);
                        log.info("tag read results {}", readResult.getStatusCode());
                        data = readResult.getBody();
                        List<Map<String, Object>> localDate = monitorPointDataAPIService.findAll(tenantId, orgCode);
                        if (CollectionUtils.isNotEmpty(data)) {
                            data.addAll(localDate);
                        } else {
                            data = localDate;
                        }
                    } else {
                        // read data from wwyt local
                        data = monitorPointDataAPIService.findAll(tenantId, orgCode);
                    }
                    if (data != null) {
                        handleData(tenantId, orgCode, data);
                    }
                } catch (Exception e) {
                    log.error("监测点数据读取异常, url={}", (config == null ? "null url" : config.getValue()), e);
                }
            });
        } catch (Exception e) {
            log.error("MonitorPointDataExtractTask run exception:", e);
        }
    }



    @SuppressWarnings("unchecked")
    private void handleData(Long tenantId, String orgCode, List<Map<String, Object>> data) {
        List<MonitorPointData> list = Lists.newArrayList();
        for (Map<String, Object> tagData : data) {
            String tag = (String) tagData.get("tag");
            List<LinkedHashMap<String, Object>> values = (ArrayList) tagData.get("values");
            if (values != null && values.size() > 0) {
                for (LinkedHashMap<String, Object> valOne : values) {
                    try {
                        MonitorPointData pd = new MonitorPointData();
                        Object time = valOne.get("time");
                        if (time instanceof Long) {
                            pd.setTime(Long.parseLong(time.toString()));
                        } else if (time instanceof Integer) {
                            int timeSecond = Integer.parseInt(time.toString());
                            pd.setTime(timeSecond);
                        }
                        pd.setTenentId(tenantId);
                        pd.setOrgCode(orgCode);
                        pd.setPointCode(tag);
                        Object v = valOne.get("value");
                        if (v != null && !"null".equals(v) && !"".equals(v)) {
                            pd.setValue(Double
                                    .valueOf(String.format("%.2f", Double.valueOf(valOne.get("value").toString()))));
                            list.add(pd);
                        }
                    } catch (Exception e) {
                        log.error("MonitorPointDataHandler error", e);
                    }
                }
            }
        }
        if (list.size() > 0) {
            Map<String, MhAlarmLimitConfig> configMap = new HashMap<>();
            Map<String, Map<Integer, String>> levelMaps = new HashMap<>();
            BaseConfig switchConfig = new BaseConfig();
            Map<String, RiskEvaluationControl> dyContMap = new HashMap<>();
            try {
                defaultIMonitorPointDataHandler.handle(list, configMap, levelMaps, switchConfig, dyContMap);
            } catch (Exception e) {
                log.error("MonitorPointDataHandler error", e);
            }
        }
    }

    private HttpHeaders getHttpHeaders() {
        HttpHeaders headers = new HttpHeaders();
        MediaType mtype = MediaType.parseMediaType("text/plain; charset=utf-8");
        headers.setContentType(mtype);
        return headers;
    }

    private String toJsonBody(List<String> pointCodes) {
        StringBuilder builder = new StringBuilder();
        builder.append("[");
        for (int i = 0; i < pointCodes.size(); i++) {
            String tag = pointCodes.get(i);
            builder.append("{").append("\"tag\":").append("\"").append(tag).append("\"}");
            if (i != pointCodes.size() - 1) {
                builder.append(",");
            }
        }
        builder.append("]");
        return builder.toString();
    }

}
